package com.gzhryc.shared_device.bxscn.core.protocol.v1;

import com.gzhryc.common.IDTools;
import com.gzhryc.common.logging.Logger;
import com.gzhryc.shared_device.bxscn.core.models.*;
import com.gzhryc.shared_device.bxscn.core.protocol.v1.msg.*;
import com.gzhryc.shared_device.bxscn.core.BXSCNConstants;
import com.gzhryc.shared_device.bxscn.core.IBXSCNNetworkEventListener;
import com.gzhryc.shared_device.bxscn.core.enums.EBXSCNLeaseResultCode;
import com.gzhryc.shared_device.iot.code.dao.db.IOTLogsRecord;
import com.gzhryc.shared_device.iot.code.dao.enums.ELogType;
import com.gzhryc.shared_device.iot.code.IIOTLogServer;
import com.gzhryc.shared_device.iot.core.IOTClientEvent;
import com.gzhryc.shared_device.iot.core.IOTClientEventListener;
import com.gzhryc.shared_device.iot.core.IOTMessage;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;

public class V1_BXSCN_IOTClientEventListener implements IOTClientEventListener {

    static Logger log = Logger.getLogger(V1_BXSCN_IOTClientEventListener.class);

    private final IIOTLogServer logServer;
    private final IBXSCNNetworkEventListener eventListener;

    public V1_BXSCN_IOTClientEventListener(IIOTLogServer logServer, IBXSCNNetworkEventListener eventListener){
        this.logServer = logServer;
        this.eventListener = eventListener;
    }

    @Override
    public void active(IOTClientEvent event) {

    }

    @Override
    public void receiveMessage(IOTClientEvent event) {
        String content = event.getMessage().getString();
        if (content != null) {
            content = content.trim();
        }
        try {
            BaseMessage message = null;
            Matcher mat = BXSCNConstants.CmdPattern.matcher(content);
            if (mat.find()) {
                message = new BaseMessage();
                message.setCmd(mat.group(1));
                message.setDeviceSn(event.getDeviceSn());
                message.setCheckCode(mat.group(3));
                //消息ID
                String[] data = mat.group(2).split(",");
                if(CNRequest.CMD.equals(message.getCmd())){
                    //CN命令没有消息ID
                    message.setData(data);
                }else{
                    message.setMessageId(data[0]);
                    message.setData(ArrayUtils.remove(data, 0));
                }
            }
            // 记录iot日志
            IOTLogsRecord eventEntity = new IOTLogsRecord();
            eventEntity.setType(ELogType.DeviceLog.name());
            eventEntity.setIotTopic(event.getMessage().getTopic());
            eventEntity.setDeviceSn(event.getDeviceSn());
            if (message != null) {
                eventEntity.setCommand(message.getCmd());
                eventEntity.setMsgId(message.getMessageId());
            }
            eventEntity.setContent(content);
            eventEntity.setProtocolType(BXSCNConstants.ProtocolTypeV1);
            eventEntity.setIotId(event.getClient().getIOTNote().getId());
            logServer.send(eventEntity);

            if (message == null) {
                log.error("无法识别的报文，" + event.getMessage().getString());
                return;
            }

            if (BWResponse.CMD.equals(message.getCmd())) {
                // 设备自主租借命令
                BWResponse bwResponse = new BWResponse(message);

                BXSCNLeaseResult leaseResult = new BXSCNLeaseResult();
                leaseResult.setDeviceSn(bwResponse.getDeviceSn());
                leaseResult.setMsgId(bwResponse.getMessageId());
                leaseResult.setSlotNum(bwResponse.getSlotNum());
                leaseResult.setPortableBatterySn(bwResponse.getMobilePowerId());
                leaseResult.setPower(bwResponse.getMobilePowerSupplyVolume());
                leaseResult.setResultCode(bwResponse.getResultCode());
                leaseResult.setTradeNo(bwResponse.getTradeNo());

                if (bwResponse.getResultCode() == 1 && StringUtils.isNotBlank(bwResponse.getMobilePowerId())) {
                    leaseResult.setResultCode(EBXSCNLeaseResultCode.Success.index());
                } else if (bwResponse.getResultCode() == 100) {
                    leaseResult.setResultCode(EBXSCNLeaseResultCode.NotRemoved.index());
                } else if (bwResponse.getResultCode() == 110) {
                    leaseResult.setResultCode(EBXSCNLeaseResultCode.LockException.index());
                } else {
                    leaseResult.setResultCode(EBXSCNLeaseResultCode.Fail.index());
                }

                eventListener.leaseReceiveHandle(leaseResult);

                //发送BR确定
                BRRequest brRequest = new BRRequest();
                brRequest.setMessageId(IDTools.getTimestampSecondID());
                brRequest.setTradeNo(bwResponse.getTradeNo());

                IOTMessage backMessage = new V1_BXSCN_IOTMessage(brRequest.getMessage());
                backMessage.setMessageId(brRequest.getMessageId());
                backMessage.setDeviceSn(event.getDeviceSn());
                backMessage.setCmd(brRequest.getCmd());
                backMessage.setTopic("/" + event.getDeviceSn() + "/user/get");
                event.getClient().send(backMessage);

            } else if (FBResponse.CMD.equals(message.getCmd())) {
                // 设备自定义弹出命令
                FBResponse fbResponse = new FBResponse(message);

                BXSCNLeaseResult leaseResult = new BXSCNLeaseResult();
                leaseResult.setDeviceSn(fbResponse.getDeviceSn());
                leaseResult.setMsgId(fbResponse.getMessageId());
                leaseResult.setSlotNum(fbResponse.getSlotNum());
                leaseResult.setPortableBatterySn(fbResponse.getMobilePowerId());
                leaseResult.setPower(fbResponse.getMobilePowerSupplyVolume());
                leaseResult.setResultCode(fbResponse.getResultCode());
                leaseResult.setTradeNo(fbResponse.getTradeNo());

                if (fbResponse.getResultCode() == 1 && StringUtils.isNotBlank(fbResponse.getMobilePowerId())) {
                    leaseResult.setResultCode(EBXSCNLeaseResultCode.Success.index());
                } else if (fbResponse.getResultCode() == 100) {
                    leaseResult.setResultCode(EBXSCNLeaseResultCode.NotRemoved.index());
                } else if (fbResponse.getResultCode() == 110) {
                    leaseResult.setResultCode(EBXSCNLeaseResultCode.LockException.index());
                } else {
                    leaseResult.setResultCode(EBXSCNLeaseResultCode.Fail.index());
                }

                eventListener.leaseReceiveHandle(leaseResult);

                //发送BR确定
                BRRequest brRequest = new BRRequest();
                brRequest.setMessageId(IDTools.getTimestampSecondID());
                brRequest.setTradeNo(leaseResult.getTradeNo());

                IOTMessage backMessage = new V1_BXSCN_IOTMessage(brRequest.getMessage());
                backMessage.setMessageId(brRequest.getMessageId());
                backMessage.setDeviceSn(event.getDeviceSn());
                backMessage.setCmd(brRequest.getCmd());
                backMessage.setTopic("/" + event.getDeviceSn() + "/user/get");
                event.getClient().send(backMessage);

            } else if (RSRequest.CMD.equals(message.getCmd())) {
                //归还
                RSRequest rsReq = new RSRequest(message);

                BXSCNReturnNotify returnNotify = new BXSCNReturnNotify();
                returnNotify.setDeviceSn(rsReq.getDeviceSn());
                returnNotify.setMsgId(rsReq.getMessageId());
                returnNotify.setSlotNum(rsReq.getSlotNum());
                returnNotify.setPortableBatterySn(rsReq.getMobilePowerId());
                returnNotify.setPower(rsReq.getMobilePowerSupplyVolume());
                returnNotify.setResultCode(rsReq.getResultCode());

                eventListener.returnHandle(returnNotify);

                //发送RS确定
                RSResponse bsRequest = new RSResponse();
                bsRequest.setMessageId(rsReq.getMessageId());
                bsRequest.setSlotNum(returnNotify.getSlotNum());
                bsRequest.setResultCode(1);

                IOTMessage backMessage = new V1_BXSCN_IOTMessage(bsRequest.getMessage());
                backMessage.setMessageId(bsRequest.getMessageId());
                backMessage.setDeviceSn(event.getDeviceSn());
                backMessage.setCmd(bsRequest.getCmd());
                backMessage.setTopic("/" + event.getDeviceSn() + "/user/get");
                event.getClient().send(backMessage);
            } else if (FRResponse.CMD.equals(message.getCmd())) {
                //开仓协议
                FRResponse resp = new FRResponse(message);

                BXSCNOpenSlotResult openSlotResult = new BXSCNOpenSlotResult();
                openSlotResult.setDeviceSn(resp.getDeviceSn());
                openSlotResult.setSlotNum(resp.getSlotNum());
                openSlotResult.setResultCode(resp.getResultCode());
                openSlotResult.setMsgId(resp.getMessageId());

                eventListener.openSlotReceiveHandle(openSlotResult);

            } else if (ADResponse.CMD.equals(message.getCmd())) {
                //全量上报命令
                ADResponse resp = new ADResponse(message);

                BXSCNSearchResult searchResult = new BXSCNSearchResult();
                searchResult.setMessageId(resp.getMessageId());
                searchResult.setDeviceSn(resp.getDeviceSn());
                searchResult.setIccid(resp.getIccid());
                searchResult.setImsi(resp.getImsi());
                searchResult.setRssi(resp.getRssi());
                searchResult.setVersionNumber(resp.getVersion());
                searchResult.setSlotTotal(resp.getSlotTotal());

                if (resp.getItems() != null && resp.getItems().size() > 0) {
                    List<BXSCNSearchResult.SlotItem> slotItemList = new ArrayList<>();
                    for (ADResponse.SlotItem item : resp.getItems()) {
                        BXSCNSearchResult.SlotItem info = new BXSCNSearchResult.SlotItem();
                        info.setSlotNum(item.getSlotId());
                        if(!"NULL".equals(item.getMobilePowerId())) {
                            info.setSubDeviceSn(item.getMobilePowerId());
                        }
                        info.setRevertState(item.getRevertState());
                        info.setPower(item.getSupplyVolume());
                        info.setLockState(item.getLockState());
                        slotItemList.add(info);
                    }
                    searchResult.setItems(slotItemList);
                }

                eventListener.searchResultHandle(searchResult);

                //全量归还回复
                RSResponse csResponse = new RSResponse();
                csResponse.setMessageId(resp.getMessageId());
                csResponse.setSlotNum(0);
                csResponse.setResultCode(resp.getItems().size());       //全量，这里是卡槽数量

                IOTMessage backMessage = new V1_BXSCN_IOTMessage(csResponse.getMessage());
                backMessage.setMessageId(csResponse.getMessageId());
                backMessage.setDeviceSn(event.getDeviceSn());
                backMessage.setCmd(csResponse.getCmd());
                backMessage.setTopic("/" + event.getDeviceSn() + "/user/get");
                event.getClient().send(backMessage);

            } else if (FAResponse.CMD.equals(message.getCmd())) {
                //强制弹出
                FAResponse faResponse = new FAResponse(message);

                BXSCNEjectResult ejectResult = new BXSCNEjectResult();
                ejectResult.setDeviceSn(faResponse.getDeviceSn());
                ejectResult.setMsgId(faResponse.getMessageId());
                ejectResult.setResultCode(faResponse.getResultCode());

                eventListener.ejectReceiveHandle(ejectResult);

            } else if (CNRequest.CMD.equals(message.getCmd())) {
                CNRequest cnRequest = new CNRequest(message);

                //上线
                eventListener.online(cnRequest.getDeviceSn(),cnRequest.getVersion(),cnRequest.getImsi(),cnRequest.getIccid(),cnRequest.getRssi());

                //回复
                CNResponse cnResponse = new CNResponse(cnRequest.getDeviceSn());
                IOTMessage backMessage = new V1_BXSCN_IOTMessage(cnResponse.getMessage());
                backMessage.setDeviceSn(event.getDeviceSn());
                backMessage.setCmd(cnResponse.getCmd());
                backMessage.setTopic("/" + event.getDeviceSn() + "/user/get");
                event.getClient().send(backMessage);
            }
        } catch (Exception e) {
            log.error("接收IOT信息错误", e);
            log.error("报文内容：{{0}}",content);
        }
    }

    @Override
    public void stateChange(IOTClientEvent event) {

    }

    @Override
    public void sendMessage(IOTMessage msg, Long iotId, String topic) {
        //记录日志
        IOTLogsRecord eventEntity = new IOTLogsRecord();
        eventEntity.setType(ELogType.CloudLog.name());
        eventEntity.setIotId(iotId);
        eventEntity.setDeviceSn(msg.getDeviceSn());
        eventEntity.setIotTopic(topic);
        eventEntity.setContent(msg.getString());
        eventEntity.setMsgId(msg.getMessageId());
        eventEntity.setProtocolType(BXSCNConstants.ProtocolTypeV1);
        eventEntity.setCommand(msg.getCmd());
        logServer.send(eventEntity);
    }
}
